from functools import wraps

from rest_framework import status

from weiwenhai_Oj.exceptions.base_exception import ServiceException
from weiwenhai_Oj.utils import log_utils
from weiwenhai_Oj.utils.global_functions import returnResponse

logger = log_utils.log('handle_exception')


def handle_exceptions(func):
    """
    全局异常处理统一处理装饰器

    使用方法:
    1. 在需要进行异常处理的函数上添加@handle_exceptions装饰器。

    返回:
        Response: 如果捕获到ServiceException，返回自定义错误信息和状态码。
                  如果捕获到其他异常，返回500内部服务器错误。
    优点：
        在ViewSet层中，常常需要捕获Service层抛出的异常，不得不加一层try catch，
        这个小小的过程混迹在业务代码中会显得非常难看和臃肿，所以使用这个统一的装饰器来统一捕获，减少重复代码，使得代码结构更清晰。
    示例:
    @handle_exceptions
    def some_view_function(request):
        # 视图逻辑
        pass

     作者：魏文海，2024年8月10日
    """

    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except ServiceException as e:
            logger.error(f"[{type(e)}]--{e.msg}")
            return returnResponse({'msg': e.msg, 'code': e.code})
        except Exception as e:
            logger.error(f"[{type(e)}]--{e}")
            return returnResponse({'code': 500, 'msg': str(e)}, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return wrapper
